﻿using DA.AnimGraph;
using OdinSerializer;
using System.Collections.Generic;
using System.Linq;

namespace DA.AnimGraph.Editor {
    internal class AGANode_BlendSpace1D : AGANode_SampleBase, IResourceNode {

        public override AGANodeModelBase modelProperty { set => model = (AGANodeModel_BlendSpace1D)value; get => model; }
        [OdinSerialize] AGANodeModel_BlendSpace1D model;

        public AGANode_BlendSpace1D(AGANodeModelBase model) : base(model) {
        }
        public override int Publish(List<PublishNode> outNodes, AGAPublisher.PublishContext context) {
            var pNode = new BlendSpace1DPNode();
            pNode.uuid = uuid;
            pNode.data = model.Publish(context);
            var index = outNodes.Count;
            outNodes.Add(pNode);
            PublishPerks(pNode, context);
            return index;
        }
        public AUID[] GetResources() {
            return model.GetResources();
        }
        public void ReplaceResourceAUID(Dictionary<AUID, AUID> uuidMapping) {
            model.ReplaceResourceAUID(uuidMapping);
        }
    }

    [ModelOf(typeof(AGANode_BlendSpace1D))]
    internal class AGANodeModel_BlendSpace1D : AGANodeModelBase {

        public AGAFieldModel_FloatLink inputPosition = new();
        public List<AGAFieldModel_BlendSpace1DClip> clips = new();

        public BlendSpace1DNode.SetupData Publish(AGAPublisher.PublishContext context) {
            clips.Sort((x, y) => {
                return x.position.CompareTo(y.position);
            });
            var clipsPos = new float[clips.Count];
            var clipIds = new int[clips.Count];
            var clipsDesc = new List<ClipLinkDesc>(clips.Count);
            for (int i = 0; i < clips.Count; i++) {
                clipsPos[i] = clips[i].position;
                var clipDesc = clips[i].clip.Publish(context);
                var index = clipsDesc.FindIndex(x => x.uuid == clipDesc.uuid);
                if (index < 0) {
                    clipsDesc.Add(clipDesc);
                    clipIds[i] = clipsDesc.Count - 1;
                } else {
                    clipIds[i] = index;
                }
            }

            return new BlendSpace1DNode.SetupData {
                inputDesc = inputPosition.Publish(context),
                clipsDesc = clipsDesc.ToArray(),
                clipsPos = clipsPos,
                clipIds = clipIds,
            };
        }

        public AUID[] GetResources() {
            return clips.Select(x => x.clip.clipKey).Where(x => x.isValid).ToArray();
        }
        public void ReplaceResourceAUID(Dictionary<AUID, AUID> uuidMapping) {
            foreach (var p in clips) {
                if (uuidMapping.TryGetValue(p.clip.clipKey, out var newId)) {
                    p.clip.clipKey = newId;
                }
            }
        }
    }

}
